<?php
session_start();
require_once("resources/const.php");

class curlHelper {
    private $mh;
    private $handles;
    private $array;

    public function __construct() {
        $this->mh = curl_multi_init();
        $this->handles = Array();
        $this->array = Array();
    }

    /*  $url is the url you wish to call, including get variables if applicable
    	$callback is a function name passed as string, the function you wish to
    	be called when the results has been returned
    	$post is the post variables if http post is to be used, passed as an assoc array
    	*/
    public function addHandle($url,$callback,$var = null,$post = false) {
        $ch = curl_init();
        if (isset($_SESSION['sid'])) {
            $var["sid"] = $_SESSION['sid'];
        }
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($post) {
            curl_setopt($ch, CURLOPT_POST,1);
            curl_setopt($ch, CURLOPT_POSTFIELDS,$var);
        } elseif (count($var)>0) {
            $first = true;
            foreach ($var as $key=>$value) {
                $url .= ($first?"?":"&") . $key . "=" . $value;
                $first = false;
            }
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        $this->array[] = $ch;
        $this->handles[(int)$ch] = $callback;
        curl_multi_add_handle($this->mh,$ch);
    }

    private function loop(&$active) {
        $mrc = 0;
        do {
            $mrc = curl_multi_exec($this->mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        return $mrc;
    }

    public function exec() {
        if (count($this->array) > 1) {
            $active = 0;
            //execute the handles
            $mrc = $this->loop($active);
            while ($active && $mrc == CURLM_OK) {
                if ($amount = curl_multi_select($this->mh) != -1) {
                    //maybe not sure wtf this select returns but I think it returns how many changes thus I loop
                    //through it with get info to get all that has happend
                    for ($i = 0;$i < $amount;$i++) {
                        if ($result = $this->fetchContent()) {
                            call_user_func($result["callback"],json_decode($result["content"],true));
                        }
                    }
                    $mrc = $this->loop($active);
                }
            }
        } elseif (count($this->array) == 1) {
            $ch = $this->array[0];
       		$result2 = curl_exec($ch);
            $handler = (int)$ch;
            if(!($result = json_decode($result2, true))) {
            	$result = $result2;
            }
            $this->close();
            return call_user_func($this->handles[$handler],$result);
        } else {
            return false;
        }
        $this->close();
        return true;
    }

    private function fetchContent() {
        if ($info = curl_multi_info_read($this->mh)) {
            if (($info['msg'] == CURLMSG_DONE) && ($info['result'] == CURLE_OK)) {
                $ch = $info['handle'];
                $array = Array("callback"=>$this->handles[(int)$ch],"content"=> curl_multi_getcontent($ch));
                return $array;
            }
        }
        return false;
    }

    public function close() {
        //close the handles
        foreach ($this->array as $ch) {
            curl_multi_remove_handle($this->mh, $ch);
            curl_close($ch);
        }
        curl_multi_close($this->mh);
    }
}
?>